Day22 [and], [or] 和 [&&], [||] 比較? What is the difference between [and]
, [or]
and [&&]
, [||]
?`
基本上而言:
and
就是 &&
(且)or
就是||
(或)and
和 &&
以及 or
和 ||
的意思雖然一樣,但就像以前在數學課學過的先乘除後加減
的概念一樣,程式中的運算子之間也具有優先順序之分。符號的&&
, ||
的優先權高於關鍵字and
, or
(https://ruby-doc.com/core/doc/keywords_rdoc.html)。
事有輕重緩急,資源要放在要緊的地方。要比較哪個運算式先處理之前,在此我們介紹一個概念:short-circuit evaluation
(又稱:短路計算、捷徑計算、最小化計算)。
當表達式的結果已經確定時,程式會節省資源,減少不必要的運算。不管是&&
.||
還是and
.or
,都會符合最短路徑計算
原則。
舉個例子來說:
a = 0
b = 1
if (a == 1 && b%2 == 1)
p "true"
else
p "false"
end # => false
在以上的例子裡,&&
代表括弧內的條件判斷必須全部為真
才成立。一開始我們指定a = 0
,因此,在if (a==1)
這個敘述為false
的情況,我們不需要走完下一條判斷式b%2 == 1 (b為奇數)
,這就是「最短路徑計算」。
&&
, ||
,不要使用 and
, or
根據RuboCop Headquarters的Ruby Style Guide:
The
and
andor
keywords are banned. The minimal added readability is just not worth the high probability of introducing subtle bugs. For boolean expressions, always use&&
and||
instead.
由於優先權(precedence)
的問題,and
and or
是很容易出bug的:
...
and
even has lower precedence than=
. 出處
因此,再次強調,使用 &&
, ||
,不要使用 and
, or
。
&&
與 and
都是且
的意思。
我的鐵人賽日記IronmanDairy
來到第22天了!!!由於第22天為偶數,IronmanDairy % 2 == 1
(除以2的餘數為1)顯示為false.
IronmanDairy = 22
p IronmanDairy % 2 == 1 && IronmanDairy == 22 #=>false
和
IronmanDairy = 22
p IronmanDairy % 2 == 1 && IronmanDairy == 22 #=>false
結果相同。
&&
和 and
可確認一串條件判斷式之中是否有false
或nil
的部分,全部為true
的情況,才會通過條件判斷。&&
和 and
都會遵循「最短路徑計算」。
=
談到優先權,開車的朋友可以聯想到路權,直行車的權利大於轉彎車。 &&
就像直行車一樣:
p IronmanDairy = 22 && IronmanDairy % 2 == 0
#undefined method `%' for nil:NilClass (NoMethodError)
上列程式竟然出現NoMethodError
!!原因是&&
有較高的優先權。
對Ruby來說,優先順序變成:
p IronmanDairy = (22 && IronmanDairy) % 2 == 0
由於IronmanDairy
尚未初始化(uninitialized),而讓22 && IronmanDairy
為NilClass
,然而NilClass 除以2是無意義的。
如果我們把同一條件判斷式,加上適當的括弧隔開:
p (IronmanDairy = 22) && (IronmanDairy % 2 == 0)
#=> true
就可以完成我們要達到的語義目的:
給定鐵人賽日記IronmanDairy
這個值為22,且22是個偶數,顯示為true.
and
的優先權低於 =
而在上述案例,若 &&
改成 and
的意思,就天差地遠了:
p IronmanDairy = 22 and IronmanDairy % 2 == 0 #=> 22
p (IronmanDairy = 22) and (IronmanDairy % 2 == 0) #=> 22
不管括弧是否存在,結果已經變成印出了IronmanDairy指定的數值22
,而不是出現我們想判斷的布林值true
,因為
IronmanDairy = 22
的 =
等號竟然比 and
的優先權還高!!
為了防止誤會大了,難以偵錯出產生的bug,請不要用and
或or
喔!
and
關鍵字與if
有的時候,我們點擊動態網站中的連結,會跳出(showup)
意想不到的視窗(suprise)
:
suprise = suprise.showup and next
寫法等同於if
(如果跳出視窗,就進行下一步next
):
next if suprise = suprise.showup
如同把 I am hungry and I eat an apple
改寫為
I wanna eat an apple if I am hungry!
把and
改if
,這樣是不是比較類似英文語法的邏輯呢?:)
or
關鍵字與unless
而有的時候,我們點擊連結想連到某個頁面,會出現錯誤訊息404:找不到此網頁
:
read_article()? or raise "Could not find this article!"
我們可以寫成:
raise "Could not find this article!" unless read_article()?
如同把 Do more exercise, or you won't be healthy!
改寫為
You won't be healthy unless you do more exercise!
最後,透過今天的Ruby面試題練習,我發現了Ruby Style Guide
,如何寫出可讀性佳、好維護的Ruby Code,是需要經過設計的。像Airbnb的Ruby Style Guide有提到,只有在簡單可寫成一行程式碼的情況再使用if/unless
,不然也是會錯誤連連喔!
Modifier if/unless usage is okay when the body is simple, the condition is simple, and the whole thing fits on one line. Otherwise, avoid modifier if/unless. link